package cn.antho.superhelp.service.impl;

import cn.antho.superhelp.domain.Order;
import cn.antho.superhelp.domain.Reservation;
import cn.antho.superhelp.domain.Staff;
import cn.antho.superhelp.dto.DistributeStaffDto;
import cn.antho.superhelp.dto.ReservationDto;
import cn.antho.superhelp.dto.ReservationTimeDto;
import cn.antho.superhelp.dto.SurveyDto;
import cn.antho.superhelp.exception.GlobalExceptionCodeEnum;
import cn.antho.superhelp.feign.StaffService;
import cn.antho.superhelp.feign.UserService;
import cn.antho.superhelp.mapper.ReservationMapper;
import cn.antho.superhelp.result.JsonResult;
import cn.antho.superhelp.service.IOrderService;
import cn.antho.superhelp.service.IReservationService;
import cn.antho.superhelp.utils.AssertUtil;
import cn.antho.superhelp.utils.CodeGenerateUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import cn.antho.superhelp.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author director
 * @since 2022-12-12
 */
@Service
public class ReservationServiceImpl extends ServiceImpl<ReservationMapper, Reservation> implements IReservationService {

    @Autowired
    private UserService userService;

    @Autowired
    private StaffService staffService;

    @Autowired
    private IOrderService orderService;

    @Override
    public JsonResult initReservation(ReservationDto reservationDto) {
        // 参数校验，使用JRS303
        // 业务校验
        Date date = new Date();
        Long userId = reservationDto.getUserId();
        String address = reservationDto.getAddress();
        // 校验用户是否存在
        JsonResult jsonResult = userService.selectOne(userId);
        AssertUtil.isTrue(jsonResult.isSuccess(), GlobalExceptionCodeEnum.ERROR);
        Object data = jsonResult.getData();
        User user = JSONObject.parseObject(JSON.toJSONString(data), User.class);
        AssertUtil.isNotNull(user, GlobalExceptionCodeEnum.ERROR);
        // 生成预约单
        Reservation reservation = new Reservation();
        reservation.setReservationNo("Y" + CodeGenerateUtils.generateOrderSn(userId));
        reservation.setAddress(address);
        reservation.setCreateTime(date);
        reservation.setUserId(userId);
        reservation.setStatusReservation(Reservation.UNASSIGNED_TO_BE_SURVEYED);
        insert(reservation);
        return JsonResult.success();
    }

    @Override
    public JsonResult distributeSurveyor(DistributeStaffDto distributeStaffDto) {
        String reservationNo = distributeStaffDto.getNo();
        Long staffId = distributeStaffDto.getStaffId();
        // 参数校验
        // 业务校验
        // 1.校验员工是否存在
        JsonResult jsonResult = staffService.selectOne(staffId);
        AssertUtil.isTrue(jsonResult.isSuccess(), GlobalExceptionCodeEnum.ERROR);
        Object data = jsonResult.getData();
        Staff staff = JSONObject.parseObject(JSON.toJSONString(data), Staff.class);
        AssertUtil.isNotNull(staff, GlobalExceptionCodeEnum.ERROR);
        // 2.校验预订单是否存在
        Reservation reservation = selectByReservationNo(reservationNo);
        AssertUtil.isNotNull(reservation, GlobalExceptionCodeEnum.ERROR);
        // 3.分配勘测师
        reservation.setSurveyor(staffId);
        reservation.setStatusReservation(Reservation.ASSIGNED_TO_BE_SURVEYED);
        updateById(reservation);
        return JsonResult.success();
    }

    @Override
    public JsonResult reservationTime(ReservationTimeDto reservationTimeDto) {
        Date date = new Date();
        String reservationNo = reservationTimeDto.getNo();
        Date reservationTime = reservationTimeDto.getReservationTime();
        // 参数校验
        // 业务校验
        boolean boo = reservationTime.after(date);
        AssertUtil.isTrue(boo, GlobalExceptionCodeEnum.ERROR);
        // 预定时间
        Reservation reservation = selectByReservationNo(reservationNo);
        reservation.setAppointmentTime(reservationTime);
        reservation.setStatusReservation(Reservation.RESERVED_TO_BE_SURVEYED);
        updateById(reservation);
        return JsonResult.success();
    }

    @Override
    public JsonResult survey(SurveyDto surveyDto) {
        String reservationNo = surveyDto.getReservationNo();
        String pics = surveyDto.getPics();
        String demand = surveyDto.getDemand();
        BigDecimal deposit = surveyDto.getDeposit();
        BigDecimal totalAmount = surveyDto.getTotalAmount();
        // 参数校验
        // 业务校验
        Date date = new Date();
        // 勘测
        Reservation reservation = selectByReservationNo(reservationNo);
        reservation.setRealAppointmentTime(date);
        reservation.setPics(pics);
        reservation.setDemand(demand);
        reservation.setStatusReservation(Reservation.SURVEYED_AND_COMMUNICATED);
        updateById(reservation);
        // TODO 调用支付服务
        // 生成订单
        Order order = new Order();
        order.setCreateTime(date);
        order.setOrderNo("D" + CodeGenerateUtils.generateOrderSn(reservation.getUserId()));
        order.setReservationNo(reservationNo);
        order.setDeposit(deposit);
        order.setTotalAmount(totalAmount);
        order.setStatusOrder(Order.CHECKOUT_SUCCESS);
        orderService.insert(order);
        return JsonResult.success();
    }

    private Reservation selectByReservationNo(String reservationNo) {
        Wrapper<Reservation> wrapper = new EntityWrapper<>();
        wrapper.eq("reservation_no", reservationNo);
        return selectOne(wrapper);
    }


}
